package com.yx.config.shiro;

import com.yx.entity.SysPermission;
import com.yx.entity.SysUser;
import com.yx.entity.SysUserRole;
import com.yx.enums.SessionEnum;
import com.yx.mapper.SysPermissionMapper;
import com.yx.mapper.SysRolePermissionMapper;
import com.yx.mapper.SysUserMapper;
import com.yx.mapper.SysUserRoleMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description: AuthRealm
 * @Auther: zcz
 * @create 2020/4/16 11:51
 */
@Slf4j
public class AuthRealm extends AuthorizingRealm {
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysPermissionMapper sysPermissionMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    /**
     * 统计在线人数
     * juc包下线程安全自增
     */
    public static final AtomicInteger sessionCount = new AtomicInteger(0);
    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
        log.info("---------------------授权----------------------");
        if (null == principals) {
            throw new UnauthenticatedException();
        }
        // 获取安全数据
        SysUser sysUser = (SysUser) principals.getPrimaryPrincipal();
        if (Objects.isNull(sysUser)) {
            throw new UnauthenticatedException();
        }
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        List<SysUserRole> userRoles = sysUserRoleMapper.getUserRoleByUserId(sysUser.getUserId());
        for (SysUserRole sysUserRole : userRoles) {
            authorizationInfo.addRole(sysUserRole.getRoleId());
            List<SysPermission> permissions;
            if ("admin".equals(sysUserRole.getRoleId())) {
                permissions = sysPermissionMapper.getAllPermissions();
            } else {
                permissions = sysPermissionMapper.getRolePermissions(sysUserRole.getRoleId());
            }
            for (SysPermission permission : permissions) {
                log.info(permission.getPermId());
                authorizationInfo.addStringPermission(permission.getPermId());
            }
        }
        log.info("---------------------授权结束----------------------");
        return authorizationInfo;
    }
    /**
     * 认证
     * @param token
     * @return
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token){
        log.info("---------------------认证----------------------");
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        System.out.println("sysUserMapper:"+sysUserMapper);

        SysUser user = sysUserMapper.getUserByUserName(username);
        if (Objects.isNull(user)) {
            throw new UnknownAccountException();
        }
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(),credentialsSalt, this.getClass().getName());
        SecurityUtils.getSubject().getSession().setAttribute(SessionEnum.LOGIN_NAME.getType(), user.getUserName());
        //会话创建，在线人数加一
        sessionCount.incrementAndGet();
        log.info("---------------------认证结束----------------------");
        return info;
    }

}
